package top.mybatisx.sql.core.sql;

import top.mybatisx.sql.core.sql.base.BaseSql;
import top.mybatisx.sql.core.sql.base.CondEnum;
import top.mybatisx.sql.core.sql.brige.ConditionAndBy;
import top.mybatisx.sql.core.table.CondColumn;
import top.mybatisx.sql.core.table.QueryColumn;
import top.mybatisx.sql.core.table.TableDef;
import top.mybatisx.sql.core.toolkit.Assert;

import java.util.List;

/**
 * 比较条件
 */
public interface Condition<T extends ConditionAndBy> extends BaseSql {

    // ********* 以下是构造 关系条件 *********
    default T and() {
        return makeCondition(CondEnum.and);
    }

    default T or() {
        return makeCondition(CondEnum.or);
    }

    default T boxL() {
        return makeCondition(CondEnum.boxL);
    }

    default T boxR() {
        return makeCondition(CondEnum.boxR);
    }

    // ********* 以下是构造 对比 条件 *********

    default T eq(QueryColumn column, Object value) {
        return eq(true, column, value);
    }

    default T eq(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.eq, value);
    }

    default T gt(QueryColumn column, Object value) {
        return gt(true, column, value);
    }

    default T gt(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.gt, value);
    }

    default T ge(QueryColumn column, Object value) {
        return ge(true, column, value);
    }

    default T ge(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.ge, value);
    }

    default T lt(QueryColumn column, Object value) {
        return lt(true, column, value);
    }

    default T lt(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.lt, value);
    }

    default T le(QueryColumn column, Object value) {
        return le(true, column, value);
    }

    default T le(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.le, value);
    }

    default T in(QueryColumn column, Object value) {
        return in(true, column, value);
    }

    default T in(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.in, value);
    }

    default T notIn(QueryColumn column, Object value) {
        return notIn(true, column, value);
    }

    default T notIn(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.notIn, value);
    }

    default T isNull(QueryColumn column) {
        return makeCondition(true, column, CondEnum.isNull, null);
    }

    default T notNull(QueryColumn column) {
        return makeCondition(true, column, CondEnum.notNull, null);
    }

    default T likeL(QueryColumn column, Object value) {
        return likeL(true, column, value);
    }

    default T likeL(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.likeL, value);
    }

    default T likeR(QueryColumn column, Object value) {
        return likeR(true, column, value);
    }

    default T likeR(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.likeR, value);

    }

    default T like(QueryColumn column, Object value) {
        return like(true, column, value);
    }

    default T like(boolean isCheck, QueryColumn column, Object value) {
        return makeCondition(isCheck, column, CondEnum.like, value);

    }

    // ********* 以下是实际执行 *********

    // 创建 关系队列
    default T makeCondition(CondEnum relationEnum) {
        // 构造 关系
        CondColumn condColumn = new CondColumn(relationEnum);
        // 加入到条件队列
        this.getCondList().add(condColumn);
        return (T) this;
    }

    // 创建 查询队列
    default T makeCondition(boolean isCheck, QueryColumn column, CondEnum condEnum, Object value) {
        // 构造 查询条件
        CondColumn condColumn = new CondColumn(isCheck, column, condEnum, value);
        // 加入到条件队列
        this.getCondList().add(condColumn);
        return (T) this;
    }

    // 获取 查询条件
    default List<CondColumn> getCondList() {
        // 1. where ; 2 having
        if (isWhere.flag == 1) {
            return whereList;
        } else if (isWhere.flag == 2) {
            return havingList;
        }
        // 3. 剩下的, 生成的 条件全部加到 joinList
        Assert.notEmpty(joinList, "on 条件前,先写 join 相关函数");
        TableDef joinTable = joinList.get(joinList.size() - 1);
        return joinTable.getJoinConditionList();
    }

}
